import { effect, track, trigger } from "./effect.js"

class ComputedRefImpl{
    getter
    setter
    _dirty = true //默认取值不用缓存
    _value
    effect
    constructor(getter, setter) {
        this.getter = getter
        this.setter = setter
        this.effect = effect(getter, {
            lazy: true, //默认不执行
            scheduler: () => {
                if (!this._dirty) {
                    // 一开始get缓存了，现在则则开启
                    this._dirty = true
                    // 【访问value存取器的时候，需要将其依赖的值收集起来】
                    trigger(this, 'set', 'value')
                }
            }
        })
    }
    // 计算属性也要收集依赖
    // 计算属性本身是一个effect
    // 里面的值更新了，就要重新执行effect 
    // 就是为了适配effect的特性，或者说本身是effect则需要依赖收集
    get value() {
        if (this._dirty) {
            this._value = this.effect() //会将用户的返回值返回
            this._dirty = false //缓存
        }
        // 【访问value存取器的时候，需要将其依赖的值收集起来】
        track(this, 'get', 'value')
        // console.log(this._value)
        return this._value
    }
    set value(newValue) {
        this.setter(newValue)
    }
}


// vue2和vue3的实现原理不一致
export function computed(getterOrOptions) {
    let getter
    let setter 
    if (typeof getterOrOptions === 'function') {
        getter = getterOrOptions
        setter = () => {
            console.warn('computed value must be readonly')
        }
    } else {
        getter = getterOrOptions.get 
        setter = getterOrOptions.set
    }
    return new ComputedRefImpl(getter, setter)
}